Skip to content

Add canonicalizations for tracking-* utilities#19827

Merged
RobinMalfait merged 4 commits intomainfrom
feat/fix-intellisense-1558
Mar 19, 2026
Merged

Add canonicalizations for tracking-* utilities#19827
RobinMalfait merged 4 commits intomainfrom
feat/fix-intellisense-1558

Conversation

@RobinMalfait
Copy link
Member

@RobinMalfait RobinMalfait commented Mar 19, 2026

This PR adds support for canonicalizations for tracking-* utilities.

This one is a bit of a funny one, if you take a look at the linked issue, there is a beautiful table:

Utility Name Value Arbitrary Value Throws Suggestion
tracking-tighter -0.05em tracking-[-0.05em]
tracking-tight -0.025em tracking-[-0.025em]
tracking-normal 0em tracking-[0em]
tracking-wide 0.025em tracking-[0.025em]
tracking-wider 0.05em tracking-[0.05em]
tracking-widest 0.1em tracking-[0.1em]

It doesn't really make sense to why only the tracking-widest one is properly suggested here. Until you look a little bit closer.

Turns out that -tracking-tighter is equivalent to tracking-wider, -tracking-tight is equivalent to tracking-wide and so on.

The way the canonicalization works internally is by generating a signature for a given utility class. If two utilities have the exact same signature, we can consider them the same. In this case tracking-widest and tracking-[0.1em] have the same signature.

One of the rules we have internally is that if we find more than one replacement utility then we don't really know what to do, so we bail. Because if you get foo or bar, which one do you pick?

If we refer to this above table again, the moment we want to canonicalize the tracking-[-0.05em] we get two suggestions: tracking-tighter and -tracking-wider, since we don't know what to do, we bail and we don't suggest anything.

So the reason that tracking-widest was suggested is just because we don't have a -tracking-tightest.

How do we fix this? Well, since we have tracking-* and -tracking-* utilities, I wanted to deprecate the -tracking-* ones for named utilities (where the values come from your theme) because that doesn't really make sense.

However, we have this exact pattern documented here: https://tailwindcss.com/docs/letter-spacing#using-negative-values Which means that I can't just deprecate those utilities.

image

Instead, I added a different rule which says that if you get multiple possible replacements, then we prefer the "positive" one, the one without the -. Also added some additional checks to make sure that if you get foo, -bar, baz, that we also bail because we know that we should prefer foo or baz over -bar, but we don't know if we should pick foo or baz...

This additional rule does solve the original issue, and we already prefer possible values over negative values in other places (related to bare values).

Fixes: tailwindlabs/tailwindcss-intellisense#1558

Test plan

  1. Existing tests pass
  2. Added regression tests to make sure that the table from above does get canonicalized correctly into the expected values.

Right now, when we _know_ that a replacement utility exist, then we use
it immediately. However, if multiple match then we don't really know
what to do so up until now we just bailed.

But the funny part is that `-tracking-wide` and `tracking-tight` result
in the exact same signature.

In this situation, we pick the positive value instead of the negative
value. If at any point, multiple positive utilities exist, we bail
again. So this only covers the above scenario where a negative and
positive utility was present.
@RobinMalfait RobinMalfait requested a review from a team as a code owner March 19, 2026 18:08
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 19, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 6c7d9216-f0c0-4cfa-899a-92725bacf674

📥 Commits

Reviewing files that changed from the base of the PR and between fcc81f9 and 5b1c46e.

📒 Files selected for processing (1)
  • CHANGELOG.md

Walkthrough

Adds tests that verify canonicalization of tracking-* candidates, including theme-defined tracking values and bracket/negative-value notations. Changes canonicalization logic in arbitraryUtilities and bareValueUtilities: when multiple replacements share a signature, the code now filters out replacements starting with - and, if exactly one non-negative replacement remains, parses and yields its parsed replacements; if multiple non-negative replacements remain, no replacements are yielded.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add canonicalizations for tracking-* utilities' clearly and concisely describes the main change: adding canonicalization support for tracking utilities.
Linked Issues check ✅ Passed The PR successfully addresses the linked issue #1558 by implementing logic to prefer positive tracking candidates over negative ones, enabling canonical suggestions for previously unsupported arbitrary tracking values.
Out of Scope Changes check ✅ Passed All changes are directly scoped to tracking utility canonicalization: the core logic in canonicalize-candidates.ts handles multi-match preferences, and test file additions verify the fix without introducing unrelated modifications.
Description check ✅ Passed The PR description clearly explains the issue with tracking-* utilities canonicalization, provides context with a detailed table, outlines the root cause, describes the solution, and references the specific issue being fixed.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/tailwindcss/src/canonicalize-candidates.test.ts (1)

1125-1156: Add a regression for the still-ambiguous branch.

These cases cover the new “one positive + negatives” path, but not the early return in packages/tailwindcss/src/canonicalize-candidates.ts, Lines 1138-1140 and Lines 1381-1383. A small fixture with two positive aliases sharing a signature and one negative alias would keep the foo / -bar / baz bail-out behavior from regressing.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/tailwindcss/src/canonicalize-candidates.test.ts` around lines 1125 -
1156, Add a test to cover the ambiguous early-return branch in
canonicalize-candidates: create a small fixture (using expectCanonicalization)
that defines two positive aliases that share the same signature and one negative
alias (e.g. the described "foo / -bar / baz" pattern) so the code path that
bails out early in canonicalize-candidates.ts (the early return handling the
ambiguous positive+negative mix) is exercised; place it alongside the existing
tracking tests in canonicalize-candidates.test.ts and assert the candidate
canonicalizes to the expected bail-out result to prevent regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/tailwindcss/src/canonicalize-candidates.test.ts`:
- Around line 1125-1156: Add a test to cover the ambiguous early-return branch
in canonicalize-candidates: create a small fixture (using
expectCanonicalization) that defines two positive aliases that share the same
signature and one negative alias (e.g. the described "foo / -bar / baz" pattern)
so the code path that bails out early in canonicalize-candidates.ts (the early
return handling the ambiguous positive+negative mix) is exercised; place it
alongside the existing tracking tests in canonicalize-candidates.test.ts and
assert the candidate canonicalizes to the expected bail-out result to prevent
regressions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3da09340-db94-4b25-8db3-4d558068fa80

📥 Commits

Reviewing files that changed from the base of the PR and between d596b0c and fcc81f9.

📒 Files selected for processing (2)
  • packages/tailwindcss/src/canonicalize-candidates.test.ts
  • packages/tailwindcss/src/canonicalize-candidates.ts

@RobinMalfait RobinMalfait merged commit 7482d47 into main Mar 19, 2026
7 checks passed
@RobinMalfait RobinMalfait deleted the feat/fix-intellisense-1558 branch March 19, 2026 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Canonical Class Suggestions Don't Work for Every Utility Class

1 participant